package io.gitee.zhangbinhub.acp.cloud.oauth.controller

import com.fasterxml.jackson.databind.ObjectMapper
import io.gitee.zhangbinhub.acp.cloud.oauth.vo.TokenUserInfoVo
import io.gitee.zhangbinhub.acp.cloud.resource.server.constant.AcpCloudResourceServerConstant
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.Parameter
import org.bouncycastle.util.encoders.Base64
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService
import org.springframework.security.oauth2.server.authorization.OAuth2TokenType
import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication
import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionAuthenticatedPrincipal
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController

@RestController
class AuthController constructor(
    private val objectMapper: ObjectMapper,
    private val oAuth2AuthorizationService: OAuth2AuthorizationService
) {
    @Operation(summary = "获取当前用户token信息", description = "根据当前登录的用户token值，返回详细信息")
    @GetMapping(value = ["/token-info"], produces = [MediaType.APPLICATION_JSON_VALUE])
    fun currToken(@Parameter(hidden = true) bearerTokenAuthentication: BearerTokenAuthentication): ResponseEntity<BearerTokenAuthentication> =
        ResponseEntity.ok(bearerTokenAuthentication).apply {
            val principal = bearerTokenAuthentication.principal as? OAuth2IntrospectionAuthenticatedPrincipal
            val userInfo = (principal?.getClaim(
                AcpCloudResourceServerConstant.TOKEN_CLAIMS_USER_INFO
            ) as? String)?.let { claimValue ->
                objectMapper.readValue(Base64.decode(claimValue), TokenUserInfoVo::class.java)
            }
            println(principal?.clientId)
            println(userInfo)
        }

    @Operation(summary = "测试权限")
    @PreAuthorize("hasAnyAuthority('test-info')")
//    @PreAuthorize("hasRole('ADMIN')")
    @GetMapping(value = ["/test-info"], produces = [MediaType.APPLICATION_JSON_VALUE])
    fun testInfo(@Parameter(hidden = true) bearerTokenAuthentication: BearerTokenAuthentication): ResponseEntity<BearerTokenAuthentication> =
        ResponseEntity.ok(bearerTokenAuthentication)

    @Operation(summary = "获取当前用户token存储的信息")
    @GetMapping(value = ["/token-store"], produces = [MediaType.APPLICATION_JSON_VALUE])
    fun tokenStoreInfo(@Parameter(hidden = true) bearerTokenAuthentication: BearerTokenAuthentication): ResponseEntity<OAuth2Authorization> =
        ResponseEntity.ok(
            oAuth2AuthorizationService.findByToken(
                bearerTokenAuthentication.token.tokenValue,
                OAuth2TokenType.ACCESS_TOKEN
            )
        )
}